package com.wgo.bpot.client.session;

import java.net.URL;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import com.wgo.bpot.common.transport.exception.StaleDataException;
import com.wgo.bpot.domain.common.CommandHistory;
import com.wgo.bpot.domain.common.UserSession;

public interface Session<T> {

	/**
	 * @return Returns the remoteUrl.
	 */
	public abstract URL getServerContextUrl();

	/**
	 * @param systemType TODO
	 * @return Returns the rootProxy.
	 */
	public abstract <S extends T> S getRootSystem(Class<S> rootSystemType);
	
	public abstract <S extends T> Collection<S> getRootSystems();

	/**
	 * Saves all new or modified concepts.
	 */
	public abstract void save() throws StaleDataException ;

	public abstract boolean isDirty(Object persistent);

	public abstract boolean isAnyDirty();
	
	public void createDbSchema() throws DomainSessionException;	
	/**
	 * Initializes a new domain model concept.
	 * 
	 * @see com.wgo.bpot.common.transport.util.DomainModelTypeNamingConvention
	 * 
	 * Examples:
	 * Project project = createConcept(Project.class);
	 * Category category = createConcept(Category.class);
	 * Requirement requirement = createConcept(Requirement.class);
	 * Stakeholder stakeholder = createConcept(Stakeholder.class);
	 * PropertySet project = createConcept(PropertySet.class);
	 * PropertyDef propertyDef = createConcept(PropertyDef.class, PropertyType.TYPES[1]);
	 * PropertyValue propertyValue = createConcept(PropertyValue.class, propertyDef);
	 * 
	 * @param <T> The type of the new concept
	 * @param clazz The class of the instance. Note this has to be a known class
	 * 				located in the domain model package {@link com.wgo.bpot.common.transport.util.DomainModelTypeNamingConvention}
	 * @param args Possible types to be set on the object. Should be of concept types. 
	 * @return The new concept instance
	 */
	@SuppressWarnings("unchecked")
	public abstract <S extends T> S createConcept(Class<S> clazz,
			Object... args);

	public Date getServerTime();
	
	public List<CommandHistory> retrieveCommandHistory(Object persistentConcept);
    
    public UserSession getUserSession();
    
}